package com.ruoyi.framework.interceptor;

import com.ruoyi.common.annotation.IgnoreAuth;
import com.ruoyi.common.config.redis.RedisService;
import com.ruoyi.common.exception.AuthTokenException;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 权限token验证，网页前端调用后台接口校验是否授权
 * 此拦截器作用方式是判断请求头里面的token是否过期或者是否有token数据判断出是否需要拦截进行跳转到登录重新登录
 * @author yangz
 * @email 17866232944@163.com
 */
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

    public static final String LOGIN_USER_KEY = "Login_User_Key";
    public static final String LOGIN_TOKEN_KEY="token";
    public static final String redis_prix="user_login:";

    @Autowired
    private RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler){
        //支持跨域请求
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,token,X-URL-PATH");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        //这里涉及到一个自定义注解，忽略验证的功能
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod){
            annotation=((HandlerMethod)handler).getMethodAnnotation(IgnoreAuth.class);
        }else {
            return true;
        }
        //如果有@IgnoreAuth注解，则不验证token 放行
        if (annotation!=null){
            //放行
            return true;
        }
        /*验证携带token 进行@LoginUser信息的注入*/
        //从header中获取token
        String token=request.getHeader(LOGIN_TOKEN_KEY);
        //header无值  从请求参数中获取
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(LOGIN_TOKEN_KEY);
        }
        //token为空 返回异常
        if (StringUtils.isBlank(token)) {
            throw new AuthTokenException("请先登录", 401);
        }

        //根据token查询用户id
        Object userId = redisService.getCacheObject(AuthorizationInterceptor.redis_prix+token);

        if (StringUtils.isNull(userId)){
            throw new AuthTokenException("登录信息过期", 401);
        }
        request.setAttribute(LOGIN_USER_KEY, userId);
        return true;
    }

}

